package controller
{
	import away3d.animators.SkeletonAnimator;
	import away3d.animators.transitions.CrossfadeTransition;
	import away3d.events.MouseEvent3D;
	
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.ui.Keyboard;
	import flash.utils.Timer;
	import flash.utils.clearTimeout;
	import flash.utils.getTimer;
	import flash.utils.setTimeout;
	
	import gameObject.GameObjectBase;
	import gameObject.Robot;
	import gameObject.WeaponMain;
	import gameObject.resources3D.MapResource;
	import gameObject.resources3D.RobotResource;
	
	import tool.FireTimer;
	
	public class MyRobotController extends GameControllerBase
	{
		private var _robot:Robot;
		private var _robotRes:RobotResource;
		private var _map:MapResource;
		
		private var isUp:Boolean = false;
		private var isDown:Boolean = false;
		private var isLeft:Boolean = false;
		private var isRight:Boolean = false;
		
		private var vx:Number=0;
		private var vy:Number=0;
		
		private var angle:Number;
		private var _bodydir:Number = 90;
		
		private var timeOut:int;
		private var _moveTimer:Timer = new Timer(1000.0/60.0);
		private var _posTimer:Timer = new Timer(30);//此时间内的方向键操作视为同时执行
		private var _lastTime:int;
		private var _keyList:Array = new Array;
		private var _holdKey:int;
		
		public var enableMove:Boolean = false;
		
		private var animator:SkeletonAnimator;
		private var transition:CrossfadeTransition = new CrossfadeTransition(0.2);
		/////////////////////////////////////////
		public function MyRobotController(MapRes:MapResource)
		{
			_map = MapRes;
		}
		
		override public function setup(target:GameObjectBase):void
		{
			super.setup(target);
			
			_robot = target as Robot;
			_robotRes = _robot.resource as RobotResource;
			
			animator = _robotRes.legMesh.animator as SkeletonAnimator;
			
			animator.play("wait",transition);
			
			Global.stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
			Global.stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
			
			//_map.groundMesh.mouseEnabled = true;
			//_map.groundMesh.addEventListener(MouseEvent3D.MOUSE_DOWN,onFloorMouseDown);
			
			_moveTimer.start();
			_moveTimer.addEventListener(TimerEvent.TIMER,updatePos);
		}
		
		override public function dispose():void
		{
			_moveTimer.stop()
			_moveTimer.removeEventListener(TimerEvent.TIMER,updatePos);
			
			_target.controller = null;
		}
		
		//通过点下地图后鼠标有没有在抬起前移动来判断是移动机甲还是旋转机身
		private function onFloorMouseDown(e:MouseEvent3D):void
		{
			_map.groundMesh.addEventListener(MouseEvent3D.MOUSE_UP,setPosition);
			Global.stage.addEventListener(MouseEvent.MOUSE_MOVE,setBodyDir);
			
			for each(var pid:int in _robot.wep_m)
			{
				if(pid>0)
				{
					Global.P2PServer.call("fire",[pid,1]);
				}
			}
		}
		
		//开始旋转机身
		private function setBodyDir(e:MouseEvent):void
		{
			Global.stage.removeEventListener(MouseEvent.MOUSE_MOVE,setBodyDir);
			_map.groundMesh.removeEventListener(MouseEvent3D.MOUSE_UP,setPosition);
			
			_map.groundMesh.addEventListener(MouseEvent3D.MOUSE_MOVE,onFloorMouseMove);
			Global.stage.addEventListener(MouseEvent.MOUSE_UP,cancelRotateBody);
			
			for each(var mainWep:WeaponMain in _robot.mainWeapons)
			{
				var mainWepCon:MainWeaponController = mainWep.controller as MainWeaponController;
				mainWepCon.fireTimer.addEventListener(TimerEvent.TIMER,mainWepFire);
				mainWepCon.fireTimer.start();
			}
		}
		//停止旋转机身
		private function cancelRotateBody(e:MouseEvent):void
		{
			for each(var mainWep:WeaponMain in _robot.mainWeapons)
			{
				var mainWepCon:MainWeaponController = mainWep.controller as MainWeaponController;
				mainWepCon.fireTimer.removeEventListener(TimerEvent.TIMER,mainWepFire);
				mainWepCon.fireTimer.stop();
			}
			
			Global.gc();
			
			_map.groundMesh.removeEventListener(MouseEvent3D.MOUSE_MOVE,onFloorMouseMove);
			Global.stage.removeEventListener(MouseEvent.MOUSE_UP,cancelRotateBody);
		}
		
		private function mainWepFire(e:TimerEvent):void
		{
			var fireTimer:FireTimer = e.currentTarget as FireTimer;
			var weapon:WeaponMain = fireTimer.weapon as WeaponMain;
			var pid:int = weapon.pid;
			
			Global.P2PServer.call("fire",[pid,1]);
		}
		
		//单击地图
		private function setPosition(e:MouseEvent3D):void
		{
			Global.stage.removeEventListener(MouseEvent.MOUSE_MOVE,setBodyDir);
			_map.groundMesh.removeEventListener(MouseEvent3D.MOUSE_UP,setPosition);
		}
		
		//计算机身朝向与鼠标坐标间的关系
		private function onFloorMouseMove(e:MouseEvent3D):void
		{
			var dix:Number = e.localPosition.x-_robot.x;
			var diy:Number = e.localPosition.z-_robot.z;
			
			var _bodydir:Number = Math.atan2(diy, dix);
			_bodydir = _bodydir*180/Math.PI + 180;
			
			//_robotRes.connector.rotationZ = legdir;
			Global.P2PServer.call("updateBodyDir",[Global.uid,_bodydir]);
		}
		
		//侦听键盘方向键的输入
		private function onKeyDown(e:KeyboardEvent):void
		{
			if(e.keyCode == Keyboard.W || e.keyCode == Keyboard.S || e.keyCode == Keyboard.A|| e.keyCode == Keyboard.D)
			{
				if(!isUp && !isDown && !isLeft && !isRight)//如果没有其它方向键已按下
				{
					var currentTime:Number = getTimer();
					if(currentTime-_lastTime > 240)//如果240ms内已有按键操作则忽略
					{
						_lastTime = currentTime;
						
						_posTimer.addEventListener(TimerEvent.TIMER,gotFirstInputKeys);//检查会不会有其它的方向键同时按下
						_posTimer.start();
						
						_keyList = [e.keyCode];
						
						if(e.keyCode == Keyboard.W)isUp = true;
						if(e.keyCode == Keyboard.S)isDown = true;
						if(e.keyCode == Keyboard.A)isLeft = true;
						if(e.keyCode == Keyboard.D)isRight = true;
					}
				}else addInputKey(e.keyCode);
				
			}
		}
		//侦听键盘方向键的输入
		private function onKeyUp(e:KeyboardEvent):void
		{
			if(e.keyCode== Keyboard.W || e.keyCode == Keyboard.S || e.keyCode == Keyboard.A|| e.keyCode == Keyboard.D)
			{
				switch(e.keyCode)
				{
					case Keyboard.W:
						isUp = false;
						break;
					case Keyboard.S:
						isDown = false;
						break;
					case Keyboard.A:
						isLeft = false;
						break;
					case Keyboard.D:
						isRight = false;
						break;
					default:
						break;
				}
				
				if(isUp + isDown + isLeft + isRight > 0)//如果还有其它方向键没有抬起，则检查是不是有其它的方向键会同时抬起
				{
					_posTimer.addEventListener(TimerEvent.TIMER,testRelaseKeys);
					_posTimer.start();
					
					_holdKey = e.keyCode;
				}
				
				if(isUp + isDown + isLeft + isRight == 0)tryStopMove();//如果所有方向键都抬起，则尝试停止移动
			}
		}
		
		private function testRelaseKeys(e:TimerEvent):void
		{
			_posTimer.removeEventListener(TimerEvent.TIMER,testRelaseKeys);
			_posTimer.stop();
			
			if(isUp + isDown + isLeft + isRight > 0)removeInputKey(_holdKey)
			else tryStopMove();
		}
		
		private function tryStopMove():void
		{
			timeOut=setTimeout(tryPlayWait,250);
			
			Global.P2PServer.call("tryStopRobot",[Global.uid,_robot.x,_robot.z]);
		}
		
		private function addInputKey(Keycode:int):void
		{
			if(!isUp && Keycode == Keyboard.W &&  _keyList.indexOf(Keycode) == -1)
			{
				isUp = true;
				_keyList.push(Keycode);
				refreshKeyList();
			}
			if(!isDown && Keycode == Keyboard.S &&  _keyList.indexOf(Keycode) == -1)
			{
				isDown = true;
				_keyList.push(Keycode);
				refreshKeyList();
			}
			if(!isLeft && Keycode == Keyboard.A &&  _keyList.indexOf(Keycode) == -1)
			{
				isLeft = true;
				_keyList.push(Keycode);
				refreshKeyList();
			}
			if(!isRight && Keycode == Keyboard.D &&  _keyList.indexOf(Keycode) == -1)
			{
				isRight = true;
				_keyList.push(Keycode);
				refreshKeyList();
			}
		}
		private function removeInputKey(KeyCode:int):void
		{
			if(KeyCode == Keyboard.W || KeyCode == Keyboard.S || KeyCode == Keyboard.A|| KeyCode == Keyboard.D)
			{
				if(_keyList.indexOf(KeyCode) != -1)
				{
					_keyList.splice(_keyList.indexOf(KeyCode),1);
					refreshKeyList();
				}
			}
		}
		
		private function gotFirstInputKeys(e:TimerEvent):void
		{
			_posTimer.removeEventListener(TimerEvent.TIMER,gotFirstInputKeys);
			_posTimer.stop();
			
			refreshKeyList();
			
			animator.play("run",transition);
		}
		
		private function refreshKeyList():void
		{
			if(_keyList.indexOf(Keyboard.W) != -1 && _keyList.indexOf(Keyboard.S) != -1)
			{
				var d:int = _keyList.indexOf(Keyboard.W)-_keyList.indexOf(Keyboard.S);
				
				if(d<0)_keyList.splice(_keyList.indexOf(Keyboard.W),1)
				else _keyList.splice(_keyList.indexOf(Keyboard.S),1)
			}
			
			if(_keyList.indexOf(Keyboard.A) != -1 && _keyList.indexOf(Keyboard.D) != -1)
			{
				d = _keyList.indexOf(Keyboard.A)-_keyList.indexOf(Keyboard.D);
				
				if(d<0)_keyList.splice(_keyList.indexOf(Keyboard.A),1)
				else _keyList.splice(_keyList.indexOf(Keyboard.D),1)
			}
			
			var dx:Number=0;
			var dy:Number=0;
			for(var i:int=0;i<_keyList.length;i++)
			{
				if(_keyList[i] == Keyboard.D)dx = 1
				else if(_keyList[i] == Keyboard.A)dx = -1;
				
				if(_keyList[i] == Keyboard.W)dy = -1
				else if(_keyList[i] == Keyboard.S)dy = 1;
			}
			
			var angle:Number = Math.atan2(dy, dx);
			Global.P2PServer.call("addPosData",[Global.uid,_robot.x,_robot.z,angle]);
			
			vx = (Math.cos(angle)*_robot.speed);
			vy = (Math.sin(angle)*_robot.speed);
			
			angle = angle*180/Math.PI-90;
			_robot.root.rotationY = angle;
			//_robotRes.legMesh.rotationY = angle;
		}
		
		private function updatePos(e:Event):void
		{
			if(enableMove)
			{
				if(vx==0 && vy==0)return;
				
				if(vx!=0)
				{
					var nextX:Number = _robot.x+ vx;
					_robot.hitArea.x = CollisionWorld.mapScaleX*(CollisionWorld.hitStartX+nextX) - _robot.hitArea.radius;
					_robot.hitArea.y = CollisionWorld.mapScaleY*(CollisionWorld.hitStartY-_robot.z) - 2*_robot.hitArea.radius;
					if(CollisionWorld.roleHitTestBuilding(_robot) == false)_robot.x = nextX
					else _robot.hitArea.x = CollisionWorld.mapScaleX*(CollisionWorld.hitStartX+_robot.x) - _robot.hitArea.radius;
				}
				
				if(vy!=0)
				{
					var nextY:Number = _robot.z- vy;
					_robot.hitArea.y = CollisionWorld.mapScaleY*(CollisionWorld.hitStartY-nextY) -2*_robot.hitArea.radius;
					_robot.hitArea.x = CollisionWorld.mapScaleX*(CollisionWorld.hitStartX+_robot.x)  -_robot.hitArea.radius;
					if(CollisionWorld.roleHitTestBuilding(_robot) == false)_robot.z = nextY
					else _robot.hitArea.y = CollisionWorld.mapScaleY*(CollisionWorld.hitStartY-_robot.z) -2*_robot.hitArea.radius;
				}
			}
			
		}
		
		private function tryPlayWait():void
		{
			clearTimeout(timeOut);
			
			if(isUp + isDown + isLeft + isRight == 0)
			{
				vx = vy = 0;
				_keyList=[];
				animator.play("wait",transition);
				
				enableMove = false;
			}
		}
		
	}
}